// 实现VueRouter类
let Vue
// VueRouter用法：new VueRouter({routes})
class VueRouter {
    constructor(options) {
        this.$options = options
        // current必须是响应式的，只有这样，current变化了，组件才会重新渲染
        // set、$set只能在响应式对象上动态添加新属性
        // 如何使current成为响应式的？
        // 方法一：new Vue(data() { return { current:window.location.hash.slice(1) || '/'}})
        // 方法二：利用Vue的隐藏api, Vue.util.defineReactive
        Vue.util.defineReactive(this, 'current', window.location.hash.slice(1) || '/')
        // this.current = window.location.hash.slice(1) || '/'
        // 当window.location.hash变化时，需要从新设置current的值
        window.addEventListener('hashchange', () => {
            console.log(this.current)
            this.current = window.location.hash.slice(1)
        })
    }
}
// 实现install方法，用于Vue.use使用，将vue-router注册为Vue的插件
// install调用时，需要传入Vue构造函数
VueRouter.install = function (_Vue) {
    Vue = _Vue
    // $router注册
    // 由于Vue.use注册VueRouter时，会立即执行install函数，而此时，new VueRouter还没有执行，router实例还未创建，所以要注册router，必须延迟执行
    // 延迟的方法：混入：Vue.mixin({beforeCreate(){}})
    Vue.mixin({
        beforeCreate() {
            // console.log(this) // 此处的this是组件实例
            // 如果当前this是根组件，它选项中必有一个router
            if (this.$options.router) {
                Vue.prototype.$router = this.$options.router
            }
        }
    })
    // 俩个全局组件：router-link、router-view
    Vue.component('router-link', {
        props: {
            to: {
                type: String,
                require: true
            },
        },
        // template: "<a>link</a>" // 由于Vue是runtime版本，所以无法解析template
        render(h) {
            // router-link用法：<router-link to="/about">XXX</router-link>
            // router-link最终渲染的结果，<a href="#/about"></a>
            return h('a', { attrs: { href: '#' + this.to } }, this.$slots.default)
        }
    })
    Vue.component('router-view', {
        // template: "<div>router-view</div>" // 由于Vue是runtime版本，所以无法解析template
        render(h) {
            // 1. 获取当前url的hash部分，window.location.hash
            // 思考：router-view也是vue组件，在日常开发中，在组件中如何获取router实例呢？this.$router,既然可以访问到router实例了，那么实例上的所有属性和方法自然而然的就可以访问了，比如：this.$router.$options.routes
            // 2. 根据hash标识从用户传入的routes中匹配对应的组件
            // 3. h(组件名)
            console.log(this.$router.$options)
            console.log(this.$router.current)
            let component = null
            const route = this.$router.$options.routes.find(route => route.path === this.$router.current)
            if (route) {
                component = route.component
            }
            return h(component)
        }
    })
}
export default VueRouter